#include "m_predis.h"
#include "agent.h"
#include "segment.h"
#include "span.h"
#include "helper.h"
// #include "skywalking_client.h"

#include <string>

void monitorpro_predis_handler(zend_execute_data *execute_data, long start_micro_time, long end_micro_time, std::string class_name, std::string function_name)
{
    // 初始化参数
    std::string operate = "";
    std::string key = "";
    std::string ip = "";
    std::string port = "";
    std::string addr = "";
    std::string err = "";
    std::string query = "";

    zval *connection = read_property(execute_data->object, "connection");
    if (connection == nullptr)
    {
        return;
    }
    zval *parameters = read_property(connection, "parameters");
    if (parameters == nullptr)
    {
        return;
    }
    zval *params = read_property(parameters, "parameters");
    if (params == nullptr)
    {
        return;
    }

    zval **z_host;
    if (SUCCESS == zend_hash_find(HASH_OF(params), "host", sizeof("host"), (void **)&z_host))
    {
        ip = Z_STRVAL_PP(z_host);
    }
    zval **z_port;
    if (SUCCESS == zend_hash_find(HASH_OF(params), "port", sizeof("port"), (void **)&z_port))
    {
        port = std::to_string(Z_LVAL_PP(z_port));
    }
    addr = ip + ":" + port;

    zval *id = func_get_arg(execute_data, 1);
    if (id != nullptr && Z_TYPE_P(id) == IS_STRING)
    {
        operate = Z_STRVAL_P(id);
    }

    query = class_name + "->" + function_name + "::" + operate;

    // SkywalkingClient *skywalking_client = SkywalkingClient::newInstance();
    // Segment *segment = skywalking_client->getSegment();
    // auto *span = segment->createSpan(SkySpanType::Exit, SkySpanLayer::Database, 8003);
    // span->setOperationName(class_name + "->" + function_name);
    // span->addTag("db.type", "redis");
    // span->addTag("db.driver", "predis");
    // span->addTag("redis.command", operate);
    // span->setPeer(addr);
    // span->setStartTime(start_micro_time / 1000);
    // span->setEndTime(end_micro_time / 1000);

    push_redis_data(addr, query, err, end_micro_time - start_micro_time);
}